package ch.christianschweizer.apps.ereservation.model;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;

@Entity
public class History implements Identifiable {

	public static class HistoryBuilder {

		private Date date;
		private HistoryType type;
		private User user;

		public HistoryBuilder date(Date date) {
			this.date = date;
			return this;
		}

		public HistoryBuilder type(HistoryType type) {
			this.type = type;
			return this;
		}

		public HistoryBuilder user(User user) {
			this.user = user;
			return this;
		}

		public History build() {
			return new History(this);
		}

	}

	public static enum HistoryType {
		CREATE, MODIFY, DELETE
	}

	@Id
	@GeneratedValue
	private Long id;

	@Version
	private long version;

	@Temporal(TemporalType.TIMESTAMP)
	private Date date;

	@Enumerated(EnumType.STRING)
	private HistoryType type;

	@ManyToOne(fetch = FetchType.LAZY)
	private User user;

	protected History() {
	}

	private History(HistoryBuilder builder) {
		date = builder.date;
		type = builder.type;
		user = builder.user;
	}

	@Override
	public Long getUniqueIdentifier() {
		return id;
	}

	public Date getDate() {
		return date;
	}

	public HistoryType getType() {
		return type;
	}

	public User getUser() {
		return user;
	}

	@Override
	public String toString() {
		return "History [id=" + id + ", date=" + date + ", type=" + type
				+ ", user=" + user + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((date == null) ? 0 : date.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((type == null) ? 0 : type.hashCode());
		result = prime * result + ((user == null) ? 0 : user.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		History other = (History) obj;
		if (date == null) {
			if (other.date != null) {
				return false;
			}
		} else if (!date.equals(other.date)) {
			return false;
		}
		if (id == null) {
			if (other.id != null) {
				return false;
			}
		} else if (!id.equals(other.id)) {
			return false;
		}
		if (type != other.type) {
			return false;
		}
		if (user == null) {
			if (other.user != null) {
				return false;
			}
		} else if (!user.equals(other.user)) {
			return false;
		}
		return true;
	}

}
